package com.erikpasternak.vader;

import java.util.Arrays;
import java.util.HashMap;

import android.app.Activity;
import android.app.Fragment;
import android.database.Cursor;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.erikpasternak.vader.DrinksAdapter.Drink;
import com.erikpasternak.vader.DrinksAdapter.Ingredient;

public class DrinkPickerFragment extends Fragment implements View.OnClickListener,
        OnItemClickListener, OnCheckedChangeListener {
    private final static String TAG = "DrinkPicker";

    private static final boolean DEBUG = false;

    private final HashMap<String, ViewGroup> mIngredients = new HashMap<String, ViewGroup>();
    private final EditText[] mIngCounts = new EditText[SharedPrefsHelper.MAX_INGREDIENTS];

	private VaderActivity.VaderStateListener mListener;
    private AdkHelper mAdkHelper;
    private DrinkDbHelper mDbHelper;
    private DrinkPourHelper mDrinkPourHelper;
    private int mMaxUnits = 24;

    private float mCost = 0;
    private String mName;

    private TextView mTitle;
    private Button mCancel;
    private Button mMix;
    private ListView mListView;
    private EditText mDrinkFilter;
    private TextView mComments;
    private CheckBox mShowAll;

    private int mCurrentIngredient = 0;
    private byte[][] mIngredientMessages;

    private final AdkHelper.Listener mAdkListener = new AdkHelper.Listener() {

        public void onSendFailed(int command) {
            if (command == AdkHelper.COMMAND_MIX) {
                Toast.makeText(getActivity(), "Error sending, try again.", Toast.LENGTH_SHORT)
                        .show();
                mListener.onStateChange(VaderActivity.STATE_DRINK);
            }
        }

        public void onMessageReceived(int command, int length, byte[] data) {
            if (command == AdkHelper.ADK_COMMAND_INGREDIENT_DONE) {
                if (mIngredientMessages == null) {
                    return;
                }
                if (mCurrentIngredient == mIngredientMessages.length) {
                    mAdkHelper.sendCommand(AdkHelper.COMMAND_MIX,
                            (byte) AdkHelper.RETURN_MSG_VALUES.length, AdkHelper.RETURN_MSG_VALUES);
                } else if (mCurrentIngredient < mIngredientMessages.length){
                    byte[] values = mIngredientMessages[mCurrentIngredient];
                    mAdkHelper.sendCommand(AdkHelper.COMMAND_MIX, (byte) values.length, values);
                } else {
                    mListener.onStateChange(VaderActivity.STATE_INITIAL);
                }
                mCurrentIngredient++;
            }
        }
    };

    public DrinkPickerFragment() {
	}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
        VaderActivity va = (VaderActivity) activity;
        mListener = va.getListener();
        mAdkHelper = va.getAdkHelper();
        mDbHelper = va.getDbHelper();
        mDrinkPourHelper = va.getDrinkPourHelper();
        mMaxUnits = (new SharedPrefsHelper(activity)).getMaxUnits();
    }

    private final TextWatcher mFilterTextWatcher = new TextWatcher() {

        public void afterTextChanged(Editable s) {
            if(s.toString().endsWith("'")) {
                s.delete(s.length() - 1, s.length());
            }
            mAdapter.getFilter().filter(s);
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }

        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
        }

    };

    private final TextWatcher mQuantityTextWatcher = new TextWatcher() {

        public void afterTextChanged(Editable s) {
            int totalUnits = 0;
            float totalCost = 0;
            int i = 0;
            for (ViewGroup ingredient : mIngredients.values()) {
                TextView quantity = (TextView) ingredient.findViewById(R.id.q);
                CharSequence valString = quantity.getText();
                TextView cost = (TextView) ingredient.findViewById(R.id.c);
                CharSequence costString = cost.getText();
                float costNum = 0;
                if (costString.length() > 4) {
                    costString = costString.subSequence(1, costString.length() - 3);
                    try {
                        costNum = Float.parseFloat(costString.toString());
                    } catch (NumberFormatException e) {
                        // Do nothing
                    }
                }
                if (!TextUtils.isEmpty(valString)) {
                    int val = Integer.parseInt(valString.toString());
                    if (val < 0) {
                        val = 0;
                        quantity.setText("0");
                    } else {
                        totalUnits += val;
                    }
                    totalCost += costNum * val / 2;
                }
                i++;
            }
            mCost = totalCost;
            if (totalCost != 0) {
                mTitle.setText("Pick your poison ($" + totalCost + ")");
            } else {
                mTitle.setText("Pick your poison");
            }
            if (totalUnits > mMaxUnits) {
                String changedString = s.toString();
                if (!TextUtils.isEmpty(changedString)) {
                    int val = Integer.parseInt(changedString);
                    if (val == 0) {
                        return;
                    }
                    val = Math.max(0, val - (totalUnits - mMaxUnits));
                    s.clear();
                    s.append(Integer.toString(val));
                }
            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }

        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
        }
    };

    private DrinksAdapter mAdapter;
    private Cursor mCursor;

    @Override
    public void onResume() {
        super.onResume();

        mCursor = mDbHelper.queryDrinks();
        mAdapter = new DrinksAdapter(getActivity(), mCursor, mShowAll.isChecked());
        mListView.setAdapter(mAdapter);

        mListView.setItemsCanFocus(false);
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        mDrinkFilter.addTextChangedListener(mFilterTextWatcher);

        mAdkHelper.addListener(mAdkListener);

        Log.d(TAG, "Resuming!!!!!");
        if (DEBUG) {
            if (mAdkHelper.isReady()) {
                mTitle.setText("Accessory ready");
            } else {
                Log.d(TAG, "mAccessory is null");
                mTitle.setText("Null accessory");
            }
        }
	}

    @Override
    public void onPause() {
        super.onPause();
        mAdkHelper.removeListener(mAdkListener);
        mListView.setAdapter(null);
        if (mCursor != null) {
            mCursor.close();
        }
    }


	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle bundle) {
        View view = inflater.inflate(R.layout.drink_picker, parent, false);
        mTitle = (TextView) view.findViewById(R.id.title);
        mCancel = (Button) view.findViewById(R.id.cancel);
        mCancel.setOnClickListener(this);
        mMix = (Button) view.findViewById(R.id.mix);
        mMix.setOnClickListener(this);

        mShowAll = (CheckBox) view.findViewById(R.id.show_all);
        mShowAll.setOnCheckedChangeListener(this);

        mListView = (ListView) view.findViewById(R.id.drink_list);
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        mListView.setOnItemClickListener(this);
        mDrinkFilter = (EditText) view.findViewById(R.id.drink_filter);
        mComments = (TextView) view.findViewById(R.id.comment);

        SharedPrefsHelper prefsHelper = new SharedPrefsHelper(getActivity());
        String[] ingredients = prefsHelper.getIngredients();
        mIngredients.clear();
        int i = 0;
        for (; i < ingredients.length; i += 2) {
            ViewGroup ingredientView = (ViewGroup) view
                    .findViewById(DrinksAdapter.INGREDIENT_VIEW_IDS[i / 2]);
            TextView name = (TextView) ingredientView.findViewById(R.id.i);
            name.setText(ingredients[i]);
            if (!TextUtils.isEmpty(ingredients[i + 1])) {
                float amount = 0;
                try {
                    amount = Float.parseFloat(ingredients[i + 1]);
                } catch (NumberFormatException e) {
                    // ignore
                }
                if (amount != 0) {
                    TextView cost = (TextView) ingredientView.findViewById(R.id.c);
                    cost.setText("$" + ingredients[i + 1] + "/oz");
                }
            }
            EditText quantity = (EditText) ingredientView.findViewById(R.id.q);
            quantity.addTextChangedListener(mQuantityTextWatcher);

            mIngredients.put(ingredients[i], ingredientView);
            mIngCounts[i / 2] = quantity;
        }
        for (; i < SharedPrefsHelper.MAX_INGREDIENTS * 2; i += 2) {
            view.findViewById(DrinksAdapter.INGREDIENT_VIEW_IDS[i / 2]).setVisibility(View.GONE);
        }
		return view;
	}

	public void onClick(View v) {
		if (v.getId() == R.id.cancel) {
			mListener.onStateChange(VaderActivity.STATE_INITIAL);
		} else {
		    sendDrink();
		}
	}

    private void sendDrink() {
        mIngredientMessages = new byte[mIngCounts.length][2];
	    int length = 0;
	    for (int i = 0; i < mIngCounts.length; i++) {
	        if (mIngCounts[i] != null) {
	            String count = mIngCounts[i].getText().toString();
	            if (!TextUtils.isEmpty(count)) {
	                int q = Integer.parseInt(count);
	                if (q > 0) {
                        mIngredientMessages[length][0] = (byte) i;
                        mIngredientMessages[length][1] = (byte) q;
                        length++;
	                }
	            }
	        }
	    }
        if (length == 0) {
            Toast.makeText(getActivity(), "No liquer selected!", Toast.LENGTH_SHORT).show();
            return;
        }
        mIngredientMessages = Arrays.copyOf(mIngredientMessages, length);
        mDrinkPourHelper.setIngredientMessages(mIngredientMessages);
        mDrinkPourHelper.setCost(mCost);
        mDrinkPourHelper.setName(mName);
        mDrinkPourHelper.setComments(mComments.getText().toString());
        mListener.onStateChange(VaderActivity.STATE_POUR_READY);
//	    byte[] values = mIngredientMessages[0];
//	    mCurrentIngredient = 1;
//        Log.d(TAG, "Sending first ingredient");
//        mAdkHelper.sendCommand(AdkHelper.COMMAND_MIX, (byte) values.length, values);
	}

    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
        mAdapter.setSelection(id);
        Drink drink = mAdapter.getItem(position);
        mName = drink.mName;
        setIngredients(drink);
    }

    private void setIngredients(Drink drink) {
        for (ViewGroup view : mIngredients.values()) {
            ((EditText) view.findViewById(R.id.q)).setText("0");
        }

        for (int i = 0; i < drink.mNumIngredients; i++) {
            Ingredient ingredient = drink.mIngredients.get(i);
            String name = ingredient.name;

            if (mIngredients.containsKey(name)) {
                ViewGroup view = mIngredients.get(name);
                EditText quantity = (EditText) view.findViewById(R.id.q);
                quantity.setText(Integer.toString(ingredient.amount));
            }
        }

        mComments.setText(drink.mComments);
    }

    public void onCheckedChanged(CompoundButton button, boolean isChecked) {
        long selection = mAdapter.getSelection();
        mAdapter = new DrinksAdapter(getActivity(), mCursor, isChecked);
        mAdapter.setSelection(selection);
        mListView.setAdapter(mAdapter);
    }
}
